package com.atguigu.gmall.pms.service.impl;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.feign.GmallSmsClient;
import com.atguigu.gmall.pms.mapper.SkuMapper;
import com.atguigu.gmall.pms.mapper.SpuDescMapper;
import com.atguigu.gmall.pms.service.SkuAttrValueService;
import com.atguigu.gmall.pms.service.SkuImagesService;
import com.atguigu.gmall.pms.service.SpuAttrValueService;
import com.atguigu.gmall.pms.vo.SkuVO;
import com.atguigu.gmall.pms.vo.SpuAttrValueVo;
import com.atguigu.gmall.pms.vo.SpuVO;

import com.atguigu.gmall.sms.vo.SkuSaleVO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.common.bean.PageResultVo;
import com.atguigu.gmall.common.bean.PageParamVo;

import com.atguigu.gmall.pms.mapper.SpuMapper;
import com.atguigu.gmall.pms.service.SpuService;


@Service("spuService")
public class SpuServiceImpl extends ServiceImpl<SpuMapper, SpuEntity> implements SpuService {
    /**
     * 什么时候使用mapper，service呢
     * 能使用mapper尽量不适用service
     * 1.service中因为永很多的事务处理，在调用的话回出现事务嵌套问题
     * 2.使用service业务层出现网状结构
     * 因为service一般是直接操作mapper的，controller直接操作service的
     * 在service中操作service，不利于后期代码的维护和修改
     *
     */
    @Autowired
    SpuDescMapper descMapper;
    @Autowired
    SpuAttrValueService baseAttrService;
    @Autowired
    SkuMapper skuMapper;
    @Autowired
    SkuImagesService imagesService;
    @Autowired
    SkuAttrValueService saleAttrService;
    /**
     * 优惠方式
     * 远程调用sms
     */
    @Autowired
    GmallSmsClient smsClient;
    @Override
    public PageResultVo queryPage(PageParamVo paramVo) {
        IPage<SpuEntity> page = this.page(
                paramVo.getPage(),
                new QueryWrapper<SpuEntity>()
        );

        return new PageResultVo(page);
    }

    @Override
    public PageResultVo querySpuInfo(PageParamVo pageParamVo, Long categoryId) {
        //封装查询条件
        QueryWrapper<SpuEntity> wrapper = new QueryWrapper<>();
        //如果id不为0，要根据分类id查，否则查询全部
        if (categoryId != 0){
            wrapper.eq("category_id",categoryId );
        }
        //如果用户输入了检索条件，根据检索条件查
        String key = pageParamVo.getKey();
        if (StringUtils.isNotBlank(key)){
            wrapper.and(t->t.like("name",key).or().like("id",key));
        }

        return new PageResultVo(this.page(pageParamVo.getPage(),wrapper));
    }

    /**day3
     * 大保存
     * @param spu
     */
    @Override
    public void bigsave(SpuVO spu) {
        //1.保存spu相关信息
        //1.1 保存pms_spu
        spu.setCreateTime(new Date());
        spu.setUpdateTime(spu.getCreateTime());
        this.save(spu);

        Long spuId = spu.getId();
        /**
         * 保存的思路：
         * 1.有mapper
         * 2.mapper.insert
         * 3.new一个需要保存的对象
         * 4.从前端获取到的数据中选择需要的数据
         * 5.为这个new对象设置进参数
         */
        //1.2 保存pms_spu_desc
        List<String> spuImages = spu.getSpuImages();
        if(!CollectionUtils.isEmpty(spuImages)){
            SpuDescEntity spuDescEntity = new SpuDescEntity();
            spuDescEntity.setSpuId(spuId);
            spuDescEntity.setDecript(StringUtils.join(spuImages,","));
            this.descMapper.insert(spuDescEntity);
        }
        //1.3 保存pms_spu_attr_value 基本属性信息
        List<SpuAttrValueVo> baseAttrs = spu.getBaseAttrs();
        if (!CollectionUtils.isEmpty(baseAttrs)){
            /**
             * 这里saveBatch需要的是entity类型的返回值，将vo类型转换成
             * 方式一：1.new一个entity集合
             *        2.将vo集合遍历出来，用entity集合来接收。
             * 方式二：使用流操作（Stream表达式）
             *          大多数的集合操作都可以用到
             *          map  filter  reduce
             */

            this.baseAttrService.saveBatch(baseAttrs.stream().map(spuAttrValueVo -> {
                //这里面的操作本质上就是将遍历出来的vo对象复制给entity对象
                SpuAttrValueEntity spuAttrValueEntity = new SpuAttrValueEntity();
                BeanUtils.copyProperties(spuAttrValueVo,spuAttrValueEntity);
                spuAttrValueEntity.setSpuId(spuId);
                return spuAttrValueEntity;
            }).collect(Collectors.toList()) );
        }


        //2.保存sku相关信息
        List<SkuVO> skus = spu.getSkus();
        if (CollectionUtils.isEmpty(skus)){
            return;
        }
        skus.forEach(skuVO -> {
            //2.1 保存pms_sku
            skuVO.setSpuId(spuId);
            skuVO.setCategoryId(spu.getCategoryId());
            skuVO.setBrandId(spu.getBrandId());
            //获取图片列表中的第一张图片作为默认图片
            List<String> images = skuVO.getImages();
            if (!CollectionUtils.isEmpty(images)){
                skuVO.setDefaultImage(
                        StringUtils.isNotBlank(
                                skuVO.getDefaultImage()) ? skuVO.getDefaultImage() : images.get(0));
            }
            this.skuMapper.insert(skuVO);
            Long skuId = skuVO.getId();

            //2.2 保存pms_sku_images
            if (!CollectionUtils.isEmpty(images)){
                this.imagesService.saveBatch(images.stream().map(image ->{
                    SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                    skuImagesEntity.setSkuId(skuId);
                    skuImagesEntity.setUrl(image);
                    skuImagesEntity.setDefaultStatus(StringUtils.equals(image,skuVO.getDefaultImage()) ? 1 : 0);
                    return skuImagesEntity;
                }).collect(Collectors.toList()));
            }
            //2.3 保存pms_sku_attr_value
            List<SkuAttrValueEntity> saleAttrs = skuVO.getSaleAttrs();
            if(!CollectionUtils.isEmpty(saleAttrs)){
                saleAttrs.forEach(skuAttrValueEntity -> {
                    skuAttrValueEntity.setSkuId(skuId);
                });
                this.saleAttrService.saveBatch(saleAttrs);
            }
            //3.保存营销相关信息
            // 3.1. 保存sms_sku_bounds
            // 3.2. 保存sms_sku_full_reduction
            // 3.3. 保存sms_sku_ladder
            SkuSaleVO skuSaleVO = new SkuSaleVO();
            BeanUtils.copyProperties(skuVO,skuSaleVO);
            skuSaleVO.setSkuId(skuId);
            this.smsClient.saveSales(skuSaleVO);

        });


    }

    public static void main(String[] args) {

        List<User> users = Arrays.asList(
                new User("柳岩", 20, false),
                new User("马蓉", 21, false),
                new User("小鹿", 22, false),
                new User("隔壁老王", 23, true),
                new User("小亮", 24, true),
                new User("百合", 25, false),
                new User("亦凡", 26, true),
                new User("柏芝", 27, false)
        );

        //集合之间的转化
        //map:
            //遍历输出
        users.stream().map(User::getName).collect(Collectors.toList()).forEach(System.out::println);
            //对象输出
        users.stream().map(user -> {
            Person person = new Person();
            person.setUname(user.getName());
            person.setAge(user.getAge());
            return person;
        }).collect(Collectors.toList()).forEach(System.out::println);

        //filter:
            //filter添加过滤条件输出
        users.stream().filter(user -> user.getAge()>20).collect(Collectors.toList()).forEach(System.out::println);
        users.stream().filter(User::getSex).collect(Collectors.toList()).forEach(System.out::println);

        // reduce
        System.out.println(users.stream().map(User::getAge).reduce((a, b) -> a + b).get());

    }


}
@Data
@AllArgsConstructor
@NoArgsConstructor
class User{
    private String name;
    private Integer age;
    private Boolean sex;
}

@Data
class Person{
    private String uname;
    private Integer age;
}